﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using Google.GData.Client;
using Google.Documents;

namespace UILibrary
{
    public class TreeViewDocuments
    {
        internal delegate void AddTreeViewNodeDelegate(TreeNode Node);
        internal delegate TreeNode AddTreeNodeCollectionDelegateA(TreeNodeCollection Parent, Document Entry);
        internal delegate void AddTreeNodeCollectionDelegateB(TreeNodeCollection Parent, Document Entry);

        private ImageList m_AppImageList = new ImageList();
        private List<Document> all = new List<Document>();
        private TreeNode m_NoFolder;
        public TreeView m_TreeView;
        private Document.DocumentType m_MajorType;

        public TreeViewDocuments(TreeView documentsView, Document.DocumentType majorType)
        {
            m_TreeView = documentsView;
            m_MajorType = majorType; 
            m_AppImageList.ColorDepth = ColorDepth.Depth32Bit;
            m_AppImageList.TransparentColor = Color.Transparent;
            m_AppImageList.ImageSize = new Size(20, 20);
            m_AppImageList.Images.Add("Folder", Properties.Resources.Folder);
            m_AppImageList.Images.Add("Word", Properties.Resources.Word);
            m_AppImageList.Images.Add("Excel", Properties.Resources.Excel);
            m_AppImageList.Images.Add("PowerPoint", Properties.Resources.PowerPoint);
            m_AppImageList.Images.Add("Unknown", Properties.Resources.DocSet1);
            m_AppImageList.Images.Add("PDF", Properties.Resources.PDF);
            m_TreeView.ImageList = m_AppImageList;
        }

        public void InitTree()
        {
            all.Clear();
            m_NoFolder = null;
            m_NoFolder = new TreeNode("My Cloud Docs");
            m_NoFolder.SelectedImageKey = "folder";
            m_NoFolder.ImageKey = "folder";

            m_TreeView.Nodes.Clear();
            if (m_TreeView.InvokeRequired)
            {
                AddTreeViewNodeDelegate AddNode = new AddTreeViewNodeDelegate(this.AddTreeViewNode);
                m_TreeView.Invoke(AddNode, new object[] { m_NoFolder });
            }
            else
                m_TreeView.Nodes.Add(m_NoFolder);
        }

        public void CleanUp()
        {
            m_TreeView.Nodes.Clear();
            m_TreeView.Nodes.Add("No items...");
        }

        private void AddTreeViewNode(TreeNode Node)
        {
            m_TreeView.Nodes.Add(Node);
        }

        public void AddDocumentToCollection(Document entry)
        {
            if (entry.Type == m_MajorType || entry.Type == Document.DocumentType.Folder)
                all.Add(entry);
        }

        public void ShowTree() { 
            foreach (Document entry in all) AddDocument2UI(entry);
        }

        public void AddDocument2UI(Document document)
        {
            //all.Add(document);
            // let's add those with no parents for the toplevel
            if (document.ParentFolders.Count == 0)
            {
                if (document.Type != Document.DocumentType.Folder)
                {
                    if (m_TreeView.InvokeRequired)
                    {
                        AddTreeNodeCollectionDelegateA AddTreeNode = new AddTreeNodeCollectionDelegateA(this.AddToTreeView);
                        m_TreeView.BeginInvoke(AddTreeNode, new object[] { m_NoFolder.Nodes, document });
                    }
                    else
                        AddToTreeView(m_NoFolder.Nodes, document);
                }
                else
                {
                    TreeNode n;
                    if (m_TreeView.InvokeRequired)
                    {
                        AddTreeNodeCollectionDelegateA AddTreeNode = new AddTreeNodeCollectionDelegateA(this.AddToTreeView);
                        n = (TreeNode)m_TreeView.Invoke(AddTreeNode, new object[] { m_NoFolder.Nodes, document });
                    }
                    else
                        n = AddToTreeView(m_NoFolder.Nodes, document);

                    if (m_TreeView.InvokeRequired)
                    {
                        AddTreeNodeCollectionDelegateB AddTreeNode = new AddTreeNodeCollectionDelegateB(this.AddAllChildren);
                        m_TreeView.Invoke(AddTreeNode, new object[] { n.Nodes, document });
                    }
                    else
                        AddAllChildren(n.Nodes, document);
                }
            }
        }

        private void AddAllChildren(TreeNodeCollection col, Document entry)
        {
            foreach (Document d in this.all)
            {
                if (d.ParentFolders.Contains(entry.Self))
                {
                    TreeNode n = AddToTreeView(col, d);
                    AddAllChildren(n.Nodes, d);
                }
            }
        }

        private TreeNode FindEntry(TreeNodeCollection coll, Document entry)
        {
            foreach (TreeNode n in coll)
            {
                // title is not specific enough
                Document d = n.Tag as Document;
                if (d.Id == entry.Id)
                    return n;
                TreeNode x = FindEntry(n.Nodes, entry);
                if (x != null)
                    return x;
            }
            return null;
        }

        private TreeNode AddToTreeView(TreeNodeCollection parent, Document doc)
        {
            TreeNode node = new TreeNode(doc.Title);
            node.Tag = doc;

            switch (doc.Type)
            {
                case Document.DocumentType.Document:
                    node.ImageKey = "Word";
                    node.SelectedImageKey = "Word";
                    break;
                case Document.DocumentType.Folder:
                    node.ImageKey = "Folder";
                    node.SelectedImageKey = "Folder";
                    break;
                case Document.DocumentType.PDF:
                    node.ImageKey = "PDF";
                    node.SelectedImageKey = "PDF";
                    break;
                case Document.DocumentType.Presentation:
                    node.ImageKey = "PowerPoint";
                    node.SelectedImageKey = "PowerPoint";
                    break;
                case Document.DocumentType.Spreadsheet:
                    node.ImageKey = "Excel";
                    node.SelectedImageKey = "Excel";
                    break;
                default:
                    node.ImageKey = "Unknown";
                    node.SelectedImageKey = "Unknown";
                    break;
            }


            parent.Add(node);
            return node;

        }

        private TreeNodeCollection FindParentTreeNode(TreeNodeCollection coll, Document doc)
        {
            foreach (TreeNode n in coll)
            {
                Document d = n.Tag as Document;
                if (doc.ParentFolders.Contains(d.Self))
                {
                    // found it.
                    return n.Nodes;
                }
                TreeNodeCollection x = FindParentTreeNode(n.Nodes, doc);
                if (x != null)
                    return x;
            }

            return null;
        }

        private TreeNodeCollection CreateParentTreeNode(Document doc)
        {
            TreeNode ret = null;
            foreach (Document d in this.all)
            {
                if (doc.ParentFolders.Contains(d.Self))
                {
                    TreeNodeCollection parent = null;
                    if (d.ParentFolders.Count != 0)
                    {
                        parent = FindParentTreeNode(m_TreeView.Nodes, d);
                    }
                    ret = AddToTreeView(parent == null ? m_TreeView.Nodes : parent, d);
                    return ret.Nodes;
                }
            }
            return m_TreeView.Nodes;
        }

    }
}
